package br.com.musclebook.bean.wizard.routine;

import java.io.Serializable;
import java.util.Iterator;

import javax.faces.bean.NoneScoped;
import javax.inject.Inject;
import javax.inject.Named;

import org.primefaces.model.DefaultTreeNode;
import org.primefaces.model.TreeNode;

import br.com.musclebook.entity.ExecutionSet;
import br.com.musclebook.entity.ExerciseExecutionSet;
import br.com.musclebook.entity.RoutineDay;
import br.com.musclebook.entity.RoutineDayTraining;

@Named
@NoneScoped
public class ExerciseExecutionSetWizardBean implements Serializable {

    private static final long serialVersionUID = 1L;

    @Inject
    private RoutineWizardBean routineWizardBean;

    public void handleAddingExerciseNode(ExerciseExecutionSet exerciseExecSetToAdd) {
	if (exerciseExecSetToAdd.getExercise() == null)
	    return;

	boolean found = false;
	for (TreeNode t1Node : this.routineWizardBean.getExerciseTree().getChildren()) { // days
	    RoutineDay routineDay = (RoutineDay) t1Node.getData();
	    if (routineDay.getDayOfWeek().equals(exerciseExecSetToAdd.getRoutineDayTraining().getRoutineDay().getDayOfWeek())) {
		for (TreeNode t2Node : t1Node.getChildren()) { // categories
		    RoutineDayTraining routineDayTraining = (RoutineDayTraining) t2Node.getData();
		    if (routineDayTraining.getExerciseCategory().equals(exerciseExecSetToAdd.getRoutineDayTraining().getExerciseCategory())) {
			exerciseExecSetToAdd.setOrderNumber(routineDayTraining.getExerciseExecutionSets().size() + 1);
			routineDayTraining.addExerciseExecutionSet(exerciseExecSetToAdd);
			new DefaultTreeNode(RoutineWizardBean.EXERCISE, exerciseExecSetToAdd, t2Node);
			t2Node.setExpanded(true);
			found = true;
			break;
		    }
		}
	    }
	    if (found)
		break;
	}
    }

    public void handleAddingExecutionSetNode(ExerciseExecutionSet exerciseExecutionSetToAdd) {
	boolean found = false;
	for (TreeNode t1Node : this.routineWizardBean.getExerciseTree().getChildren()) { // days
	    RoutineDay day = (RoutineDay) t1Node.getData();
	    if (day.getDayOfWeek().equals(exerciseExecutionSetToAdd.getRoutineDayTraining().getRoutineDay().getDayOfWeek())) {
		for (TreeNode t2Node : t1Node.getChildren()) { // trainings
		    for (TreeNode t3Node : t2Node.getChildren()) { // exercises
			ExerciseExecutionSet exerciseExecutionSet = (ExerciseExecutionSet) t3Node.getData();
			if (exerciseExecutionSet.getExercise().getId().equals(exerciseExecutionSetToAdd.getExercise().getId())) {
			    ExecutionSet execSet = new ExecutionSet();
			    execSet.setExerciseExecutionSet(exerciseExecutionSet);
			    execSet.setOrderNumber(exerciseExecutionSet.getExecutionSets().size() + 1);
			    exerciseExecutionSet.addExecutionSet(execSet);

			    new DefaultTreeNode(RoutineWizardBean.EXECUTION_SET, execSet, t3Node);
			    t3Node.setExpanded(true);
			    found = true;
			    break;
			}
		    }
		    if (found)
			break;
		}
	    }
	    if (found)
		break;
	}
    }

    public void handleRemovingExecutionSetNode(ExecutionSet executionSetToRemove) {
	boolean found = false;
	for (TreeNode t1Node : this.routineWizardBean.getExerciseTree().getChildren()) { // days
	    RoutineDay day = (RoutineDay) t1Node.getData();
	    if (day.getDayOfWeek().equals(executionSetToRemove.getExerciseExecutionSet().getRoutineDayTraining().getRoutineDay().getDayOfWeek())) {
		for (TreeNode t2Node : t1Node.getChildren()) { // trainings
		    RoutineDayTraining trainingD = (RoutineDayTraining) t2Node.getData();
		    if (trainingD.getExerciseCategory().equals(executionSetToRemove.getExerciseExecutionSet().getRoutineDayTraining().getExerciseCategory())) {
			for (TreeNode t3Node : t2Node.getChildren()) { // exercises
			    for (Iterator<TreeNode> it = t3Node.getChildren().iterator(); it.hasNext();) { // executionset
				TreeNode t4Node = it.next();
				ExecutionSet data = (ExecutionSet) t4Node.getData();

				if (executionSetToRemove.getExerciseExecutionSet().getExercise().getId().equals(data.getExerciseExecutionSet().getExercise().getId()) && executionSetToRemove.getOrderNumber().equals(data.getOrderNumber())) {
				    found = true;

				    boolean found2 = false;
				    for (RoutineDay rd : this.routineWizardBean.getRoutine().getRoutineDays()) {
					if (rd.getDayOfWeek().equals(executionSetToRemove.getExerciseExecutionSet().getRoutineDayTraining().getRoutineDay().getDayOfWeek())) {
					    for (RoutineDayTraining training : rd.getRoutineDayTrainings()) {
						if (training.getExerciseCategory().equals(executionSetToRemove.getExerciseExecutionSet().getRoutineDayTraining().getExerciseCategory())) {
						    for (ExerciseExecutionSet ees : training.getExerciseExecutionSets()) {
							if (ees.getExercise().getId().equals(executionSetToRemove.getExerciseExecutionSet().getExercise().getId())) {
							    for (Iterator<ExecutionSet> it2 = ees.getExecutionSets().iterator(); it2.hasNext();) {
								ExecutionSet es = it2.next();
								if (es.getExerciseExecutionSet().getExercise().getId().equals(executionSetToRemove.getExerciseExecutionSet().getExercise().getId()) && es.getOrderNumber().equals(executionSetToRemove.getOrderNumber())) {
								    it2.remove();
								    found2 = true;
								    break;
								}
							    }
							}
							if (found2) {
							    // adjusting order number
							    int i = 1;
							    for (Iterator<ExecutionSet> it2 = ees.getExecutionSets().iterator(); it2.hasNext();) {
								ExecutionSet es = it2.next();
								es.setOrderNumber(i);
								i++;

							    }
							    break;
							}
						    }
						}
						if (found2)
						    break;
					    }
					}
					if (found2)
					    break;
				    }
				    it.remove();
				    break;
				}
			    }
			    if (found)
				break;
			}
		    }
		    if (found)
			break;
		}
	    }
	    if (found)
		break;
	}
    }

    public void handleRemovingExerciseNode(ExerciseExecutionSet exerciseExecSetToRemove) {
	boolean found = false;
	for (TreeNode t1Node : this.routineWizardBean.getExerciseTree().getChildren()) { // days
	    RoutineDay day = (RoutineDay) t1Node.getData();
	    if (day.getDayOfWeek().equals(exerciseExecSetToRemove.getRoutineDayTraining().getRoutineDay().getDayOfWeek())) {
		for (TreeNode t2Node : t1Node.getChildren()) { // trainings
		    RoutineDayTraining trainingD = (RoutineDayTraining) t2Node.getData();
		    if (trainingD.getExerciseCategory().equals(exerciseExecSetToRemove.getRoutineDayTraining().getExerciseCategory())) {
			for (Iterator<TreeNode> it = t2Node.getChildren().iterator(); it.hasNext();) { // exercises
			    TreeNode t3Node = it.next();
			    ExerciseExecutionSet exerciseExecSet = (ExerciseExecutionSet) t3Node.getData();

			    if (exerciseExecSet.getExercise().getId().equals(exerciseExecSetToRemove.getExercise().getId())) {
				found = true;

				boolean found2 = false;

				for (RoutineDay rd : this.routineWizardBean.getRoutine().getRoutineDays()) {
				    if (rd.getDayOfWeek().equals(exerciseExecSetToRemove.getRoutineDayTraining().getRoutineDay().getDayOfWeek())) {
					for (RoutineDayTraining training : rd.getRoutineDayTrainings()) {
					    if (training.getExerciseCategory().equals(exerciseExecSetToRemove.getRoutineDayTraining().getExerciseCategory())) {
						for (Iterator<ExerciseExecutionSet> it2 = training.getExerciseExecutionSets().iterator(); it2.hasNext();) {
						    ExerciseExecutionSet exerExecSetToRemove = it2.next();
						    if (exerExecSetToRemove.getExercise().getId().equals(exerciseExecSetToRemove.getExercise().getId())) {
							it2.remove();
							found2 = true;
							break;
						    }
						}
					    }
					    if (found2) {
						// adjusting order number
						int i = 1;
						for (Iterator<ExerciseExecutionSet> it2 = training.getExerciseExecutionSets().iterator(); it2.hasNext();) {
						    ExerciseExecutionSet ees = it2.next();
						    ees.setOrderNumber(i);
						    i++;

						}
						break;
					    }
					}
				    }
				    if (found2)
					break;
				}

				it.remove();
				break;

			    }

			    if (found)
				break;
			}
		    }
		    if (found)
			break;
		}
	    }
	    if (found)
		break;
	}
    }

}